package com.ay.mybatis.annotion.utils;

import com.ay.mybatis.annotion.annotation.SetValue;


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;

/* *
 * Created by Ay on 2018/11/30
 */
@Component
public class BeanUtil implements ApplicationContextAware {
    
    private ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    
    public boolean setFieldValue(Collection c) throws NoSuchMethodException, IllegalAccessException, InstantiationException {
        //得到需要设置字段的类名
        Iterator iterator = c.iterator();
        Class cla  =iterator.next().getClass();
        Field[] fields = cla.getDeclaredFields();
        
        for(Field m : fields) {
            //得到注解
            SetValue s = m.getAnnotation(SetValue.class);
            if(s != null){
                //查找类,接口无法实例化，通过springIOC容器取得实例！！！！！
                Object o = applicationContext.getBean(s.className());
                
                //参数类型一定要加！！！ 不然没有方法进行匹配
                //默认参数是空！！！！
                Class cla2 = s.className();
                
                //查找field方法
                Method[] c2m = cla2.getMethods();
                Method queryMethod = null;
                // 无法知道要调用的参数类型，只好采用遍历
                // cla2.getMethod(s.methodName(),Integer.class);
                for(Method m2 : c2m){
                    if(m2.getName().equals(s.methodName())){
                        queryMethod = m2;
                        break;
                    }
                }
                //get方法
                Method getMethod = cla.getMethod("get" + StringUtils.capitalize(s.paraNameForGet()));
                //set方法
                Method setMethod = null;
                Method[] mcla = cla.getMethods();
                for(Method m2: mcla){
                    if(m2.getName().equals("set" + StringUtils.capitalize(s.paraNameForSet()))){
                        setMethod = m2;
                        break;
                    }
                }
                iterator = c.iterator();
                while (iterator.hasNext()) {
                    Object object = iterator.next();
                    try {
                        //获取值
                        Object getField = getMethod.invoke(object);
                        //查询
                        Object field =  queryMethod.invoke(o, getField);
                        //设置值
                        setMethod.invoke(object, field);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
        return true;
    }
    
    
}
